#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<iostream>
#include<pthread.h>
#include<string.h>
#include"protocol.hpp"
struct New_sockfd{
  int  new_sockfd;
};
int work_count(struct Request& arg){
  int ret =-1;
  switch(arg.op_){
    case'+':
        ret=arg.data1_+arg.data2_;
        break;
    case '-':
        ret= arg.data1_-arg.data2_;
        break;
    case '*':
        ret=arg.data1_*arg.data2_;
        break;
    case '/':
        ret=arg.data1_/arg.data2_;
        break;
    case '%':
        ret=arg.data1_%arg.data2_;
        break;
    default:
        ret=-1;
        break;
  }
  return ret;
}

void* work_t(void* arg){
  pthread_detach(pthread_self());
  struct New_sockfd* ns=(struct New_sockfd*)arg;
  while(1){
    struct Request req;

    ssize_t r_size=recv(ns->new_sockfd,&req,sizeof(req),0);

    if(r_size<0){
      perror("recv");
      continue;
    }else if(r_size ==0){
      printf("client have shutdown\n");
      close(ns->new_sockfd);
      break;
    }
  struct Response res;
  int ret=work_count(req);
  if(ret==-1){
   // printf("error");
  res.value_=(int)NULL;
    res.reply_status=FAILED;
  }else{
    res.reply_status=SUCCESS;
    res.value_=ret;
  }
  printf("resquest is: %d %c %d =%d\n",req.data1_,req.op_,req.data2_,res.value_);
   // printf("buf is :%s \n",req);
   // memset(buf,'\0',sizeof(req));
  //  printf("please enter msg:");
   // fflush(stdout);
  //  std:: cin>>buf;
    send(ns->new_sockfd,&res,sizeof(res),0);

  }
delete ns;
}

int main(){
  //创建套接字 流式套接字
  //侦听套接字
  int listen_sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(listen_sockfd<0){
    perror("socket");
    return 0;
  }
  //绑定端口
  struct sockaddr_in addr ;
  addr.sin_family=AF_INET;
  addr.sin_port=htons(2927);
  addr.sin_addr.s_addr=inet_addr("0.0.0.0");
  int ret=  bind(listen_sockfd,(struct sockaddr*)&addr,sizeof(addr));
  if(ret<0){
    perror("bind");
    return 0;
  }
  ret = listen(listen_sockfd,2);
  if(ret<0){
    perror("listen");
    return 0;
  }

  //  printf("listen_sockfd %d\n",listen_sockfd);
  //   printf("new_sockfd %d\n",new_sockfd);
  while(1){
    
    int new_sockfd =accept(listen_sockfd,NULL,NULL);
    if(new_sockfd<0){
      perror("accept");
      return 0;
    }
    struct New_sockfd* ns= new struct New_sockfd;
    ns->new_sockfd=new_sockfd;
    
    pthread_t tid;
    ret= pthread_create(&tid,NULL,work_t,(void*)ns);
    if(ret<0){
      close(new_sockfd);
      continue;
    }

  }
  close(listen_sockfd);
  return 0;
}
